#导入相应的模块
import pygame
from pygame.locals import *
import time,random

class BaseItem:
	'''基類'''
	pygame.init()
	# 存放爆炸的列表
	ep_list = [] 

	# 爆炸圖片
	images = [pygame.image.load("./images/ep1.png"),\
					pygame.image.load("./images/ep2.png"),\
					pygame.image.load("./images/ep3.png"),\
					pygame.image.load("./images/ep4.png"),\
					pygame.image.load("./images/ep5.png"),\
					pygame.image.load("./images/ep6.png"),\
					pygame.image.load("./images/ep7.png"),\
					pygame.image.load("./images/ep8.png"),\
					pygame.image.load("./images/ep9.png"),\
					pygame.image.load("./images/ep10.png"),\
					pygame.image.load("./images/ep11.png"),\
					pygame.image.load("./images/ep12.png"),\
					pygame.image.load("./images/ep13.png"),\
					pygame.image.load("./images/ep14.png"),\
					pygame.image.load("./images/ep15.png"),\
					pygame.image.load("./images/ep16.png"),\
					pygame.image.load("./images/ep17.png")]
	# 起始分數				
	score = 0
	
	# 起始血量
	HP = 100
	
	# 存放敵機的列表
	enemylist = [] 

	# 存放敵子彈的列表
	enemy_magazine = [] 

	# 起始英雄設定存活
	hero_alive = True

	# 血量字體設定
	HP_font = pygame.font.SysFont("Arial Black",20)

	# 分數字體設定
	score_font = pygame.font.SysFont("Arial Black",20)

	# 遊戲結束字體設定
	gameover_font = pygame.font.SysFont("Arial Black",70)

	# 存放玩家的子弹列表
	hero_magazine = [] 

class Main(BaseItem):
	'''主程序函数 '''
	

	def startGame(self):
		# 创建游戏窗口，
		self.screen = pygame.display.set_mode((512,568),0,0)

		# 创建一个游戏背景
		self.background = pygame.image.load("./images/bg2.jpg")

		# 创建玩家飞机（英雄）
		hero = HeroPlane(self.screen)

		#桌布起始位置 y
		self.m = -(1536 - 568)	

		while True:
			# 绘制桌布
			self.screen.blit(self.background,(0,self.m))

			# 桌布回放
			self.m+=2
			if self.m>=0:
				self.m = -(1536 /2)

			# 顯示得分
			self.score_txt = BaseItem.score_font.render("Score :{}".format(BaseItem.score),1,(255,255,0)) # 取得分數圖片
			self.screen.blit(self.score_txt,(10,20))# 顯示分數圖片

			# 英雄血量不足時更改英雄存活狀態
			if BaseItem.HP <=0:
				BaseItem.hero_alive = False

			# 英雄存活時執行
			if BaseItem.hero_alive:  
				self.HP_txt = BaseItem.HP_font.render("HP :{}".format(BaseItem.HP),1,(255,255,0)) # 取得ＨＰ圖片
				self.screen.blit(self.HP_txt,(200,20))# 顯示ＨＰ圖片
				hero.display()# 绘制玩家飞机
			
			# 英雄死亡時執行
			else: 
				BaseItem.HP = 0 
				self.HP_txt = BaseItem.HP_font.render("HP :{}".format(BaseItem.HP),1,(255,255,0)) #取得ＨＰ圖片
				self.screen.blit(self.HP_txt,(200,20))#顯示ＨＰ圖片

				gameover_txt = BaseItem.gameover_font.render("GAME OVER",1,(255,255,255)) #取得gameover圖片
				self.screen.blit(gameover_txt,(20,200)) #顯示gameover圖片
		
			# 执行键盘控制
			key_control(hero)

			# 當英雄存活時
			if BaseItem.hero_alive:
				# 隨機繪製敵機 
				if random.choice(range(30))==10:
					BaseItem.enemylist.append(EnemyPlane(self.screen)) 

				# 隨機添加砲彈入任一敵機
				if random.choice(range(10))==1 and len(BaseItem.enemylist)>0:	
					aa = random.randrange(len(BaseItem.enemylist)) #儲存任一敵機
					BaseItem.enemy_magazine.append(Bullet2(self.screen,BaseItem.enemylist[aa].x,BaseItem.enemylist[aa].y)) #添加砲彈
					
				# 顯示敵機子彈
				for mag in BaseItem.enemy_magazine:
					mag.display()
					if mag.move(hero): #子彈移動時與英雄碰撞檢測
						BaseItem.enemy_magazine.remove(mag) #移除子彈

				# 顯示英雄子彈
				for mag in BaseItem.hero_magazine:
					mag.display()
					if mag.move():  #
						BaseItem.hero_magazine.remove(mag)
			
			#顯示敵機
			for em in BaseItem.enemylist:
				em.display()
				if em.move(hero): #敵機移動
					BaseItem.enemylist.remove(em)

			#顯示爆炸
			for explosion in BaseItem.ep_list:
				if explosion.display() == "End_explosion":
					BaseItem.ep_list.remove(explosion)

			#更新显示
			pygame.display.update()

			#定时显示
			time.sleep(0.04)
	
class HeroPlane(BaseItem):
	'''玩家飞机（英雄）'''
	def __init__(self,screen_):
		self.x = 200
		self.y = 460
		self.screen = screen_
		self.image = pygame.image.load("./images/me.png") # 載入玩家飛機圖
		
	def display(self):
		'''绘制玩家飞机'''
		self.screen.blit(self.image,(self.x,self.y))
		
	def move_left(self):
		'''左移动飞机'''
		self.x -= 20
		if self.x <= 0:
			self.x=0

	def move_right(self):
		'''右移动飞机'''
		self.x += 20
		if self.x>=406:
			self.x=406

	def fire(self):
		'''玩家發射'''
		# 只在玩家存活時執行
		if BaseItem.hero_alive:
			BaseItem.hero_magazine.append(Bullet(self.screen,self.x,self.y)) # 添加玩家子彈
			#print(BaseItem.hero_magazine) #<__main__.Bullet object at 0x03A86C30> 物件在列表中的樣子
			print(len(BaseItem.hero_magazine))
		else:
			pass

class Bullet(BaseItem):
	'''英雄子弹类'''
	def __init__(self,screen_,x,y):
		self.x = x+53
		self.y = y
		self.screen = screen_
		self.image = pygame.image.load("./images/pd.png")

	def display(self):
		'''绘制子弹'''
		self.screen.blit(self.image,(self.x,self.y))
	
	def move(self):
		self.y -= 10
		if self.y <=-20:
			return True

class Bullet2(BaseItem):
	'''敵機子弹类'''
	def __init__(self,screen_,x_,y_):
		self.x = x_
		self.y = y_
		self.screen = screen_
		self.image = pygame.image.load("./images/pd2.png")  #敵機子彈

	def display(self):
		'''绘制敵機子弹'''
		self.screen.blit(self.image,(self.x+50,self.y))
	
	def move(self,hero):
		self.y += 10
		if self.y >=600:
			return True

		# 敵機子彈與英雄的碰撞檢測
		if self.y >= hero.y and self.y <= hero.y + 50 and self.x >=hero.x-50 and self.x <= hero.x +50 :
			print("英雄被擊中")

			# 建立爆炸對象
			explosion = Explosion(self.screen,hero.x,hero.y)
			BaseItem.ep_list.append(explosion) # 添加對象入爆炸列表
			BaseItem.HP -=5 # 血量被擊中後扣5
			return True

class Explosion(pygame.sprite.Sprite,BaseItem):
	'''爆炸類'''
	def __init__(self,screen_,left_,top_):
		self.screen = screen_
		self.switch = True
		self.left = left_
		self.top = top_
		self.current_img = 0

	def display(self):
		'''當SWITCH為開時繪製爆炸'''
		if self.switch: # 爆炸開關在建立對象時為開,直到完成爆炸序列圖後再關閉
			self.screen.blit(BaseItem.images[self.current_img],(self.left-50,self.top-50))
			self.current_img += 1
			if self.current_img == len(self.images):
				self.switch = False
				return "End_explosion"
		else:
			pass

class EnemyPlane(BaseItem):
	'''敌机类'''
	def __init__(self,screen_):
		self.x = random.choice(range(408))
		self.y = -75
		self.screen = screen_
		self.image = pygame.image.load("./images/e"+str(random.choice(range(3)))+".png")
		

	def display(self):
		'''绘制敌机'''
		self.screen.blit(self.image,(self.x,self.y))
	
	def move(self,hero):
		self.y += 4
		# 敌机出屏幕
		if self.y>568:
			return True

		# 英雄子彈與敵機做碰撞檢測
		for mag in BaseItem.hero_magazine:
			if mag.x>self.x+12 and mag.x<self.x+92 and mag.y>self.y+20 and mag.y<self.y+60:
				print("敵機被英雄子彈擊中!!")
				BaseItem.score += 100 # 擊中敵機得分100
				explosion = Explosion(self.screen,mag.x-50,mag.y-50)
				BaseItem.ep_list.append(explosion)  # 添加對象入爆炸列表
				BaseItem.hero_magazine.remove(mag)
				return True

def key_control(hero_temp):
	'''键盘控制函数'''
	#执行退出操作
	for event in pygame.event.get():
		if event.type == QUIT:
			print("exit()")
			exit()

	#获取按键信息
	pressed_keys = pygame.key.get_pressed()
	#print(pressed_keys)
	#做判断，并执行对象的操作
	if pressed_keys[K_LEFT] or pressed_keys[K_a]:
		print("Left...")
		hero_temp.move_left()

	elif pressed_keys[K_RIGHT] or pressed_keys[K_d]:
		print("Right...")
		hero_temp.move_right()

	if pressed_keys[K_SPACE]:
		print("space...")
		hero_temp.fire()






game = Main()
game.startGame()